﻿using net.xBei.Helper;
using net.xBei.Models.json;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

namespace net.xBei.Models.Request {
    /// <summary>
    /// 
    /// </summary>
    public class TaskRequest {
        /// <summary>
        /// 
        /// </summary>
        public string TaskKey { get; set; } = default!;
        /// <summary>
        /// 签名
        /// </summary>
        public string Sign { get; set; } = default!;
        /// <summary>
        /// 时间戳（Unixtime）
        /// </summary>
        public long Time { get; set; }
        /// <summary>
        /// 不能太短（Length>=10）
        /// </summary>
        public string Noise { get; set; } = default!;
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="httpRequest"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public async Task<(int httpCode, ResponseData<T> resut)> IsValidAndParse<T>(HttpRequest httpRequest, string secret) {
            var (httpCode, result) = await IsValidAsync(httpRequest, secret);
            if (result.Success == false) {
                return (httpCode, ResponseData<T>.Error(result));
            }

            var body = result.Data;
            return body.TryDeserialize<T>(out var data)
                ? (200, ResponseData<T>.Ok(data))
                : (400, ResponseData<T>.Error("参数错误"));
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="httpRequest"></param>
        /// <param name="secret"></param>
        /// <returns></returns>
        public async Task<(int httpCode, ResponseData<string> result)> IsValidAsync(HttpRequest httpRequest, string secret) {
            if (string.IsNullOrWhiteSpace(Sign)
                || string.IsNullOrWhiteSpace(Noise)
                || Time == 0
                || string.IsNullOrWhiteSpace(TaskKey)) {
                return (400, ResponseData.Error("参数错误"));
            }
            string body = string.Empty;
            try {
                using var ms = new MemoryStream();
                await httpRequest.Body.CopyToAsync(ms);
                body = Encoding.UTF8.GetString(ms.ToArray());
            } catch (Exception ex) {
                return (500, ResponseData.Error(ex.Message));
            }
            if (string.IsNullOrWhiteSpace(body)) {
                return (400, ResponseData.Error("参数错误"));
            }
            if (!CheckSign(this, body, secret)) {
                return (401, ResponseData.Error("认证失败"));
            }
            return (200, ResponseData.Ok(body));
        }
        internal static bool CheckSign(TaskRequest capTaskData, string body, string secret)
            => capTaskData.Sign == $"{capTaskData.TaskKey}:{capTaskData.Time}:{secret}:{body}:{secret}:{capTaskData.Noise}".MD5Encrypt();
    }
}
